home *** CD-ROM | disk | FTP | other *** search
- /*---------------------------------------------------------------------------
-
- mac.c
-
- Macintosh-specific routines for use with Info-ZIP's UnZip 5.1 and later.
-
- This source file incorporates the contents of what was formerly macfile.c,
- which supported commands (such as mkdir()) not available directly on the
- Mac, and which also determined whether HFS (Hierarchical File System) or
- MFS (Macintosh File System) was in use.
-
- ---------------------------------------------------------------------------*/
-
-
-
- #ifdef MACOS
- #include "unzip.h"
-
- #ifndef FSFCBLen
- # define FSFCBLen (*(short *)0x3F6)
- #endif
-
- #define read_only file_attr /* for readability only */
-
- static short wAppVRefNum;
- static long lAppDirID;
- int hfsflag; /* set if disk has hierarchical file system */
-
-
-
-
-
- /**********************/
- /* Function mapattr() */
- /**********************/
-
- int mapattr()
- {
- /* only care about read-only bit, so just look at MS-DOS side of attrs */
- pInfo->read_only = (unsigned)(crec.external_file_attributes & 1);
- return 0;
-
- } /* end function mapattr() */
-
-
-
-
-
- /**************************************/
- /* Function set_file_time_and_close() */
- /**************************************/
-
- void set_file_time_and_close()
- {
- long m_time;
- DateTimeRec dtr;
- ParamBlockRec pbr;
- HParamBlockRec hpbr;
- OSErr err;
-
-
- if (outfd == 1) /* don't attempt to close or set time on stdout */
- return;
-
- close(outfd);
-
- /*
- * Macintosh bases all file modification times on the number of seconds
- * elapsed since Jan 1, 1904, 00:00:00. Therefore, to maintain
- * compatibility with MS-DOS archives, which date from Jan 1, 1980,
- * with NO relation to GMT, the following conversions must be made:
- * the Year (yr) must be incremented by 1980;
- * and converted to seconds using the Mac routine Date2Secs(),
- * almost similar in complexity to the Unix version :-)
- * J. Lee
- */
-
- dtr.year = (((lrec.last_mod_file_date >> 9) & 0x7f) + 1980);
- dtr.month = ((lrec.last_mod_file_date >> 5) & 0x0f);
- dtr.day = (lrec.last_mod_file_date & 0x1f);
-
- dtr.hour = ((lrec.last_mod_file_time >> 11) & 0x1f);
- dtr.minute = ((lrec.last_mod_file_time >> 5) & 0x3f);
- dtr.second = ((lrec.last_mod_file_time & 0x1f) * 2);
-
- Date2Secs(&dtr, (unsigned long *)&m_time);
- CtoPstr(filename);
- if (hfsflag) {
- hpbr.fileParam.ioNamePtr = (StringPtr)filename;
- hpbr.fileParam.ioVRefNum = gnVRefNum;
- hpbr.fileParam.ioDirID = glDirID;
- hpbr.fileParam.ioFDirIndex = 0;
- err = PBHGetFInfo(&hpbr, 0L);
- hpbr.fileParam.ioFlMdDat = m_time;
- if ( !fMacZipped )
- hpbr.fileParam.ioFlCrDat = m_time;
- hpbr.fileParam.ioDirID = glDirID;
- if (err == noErr)
- err = PBHSetFInfo(&hpbr, 0L);
- if (err != noErr)
- printf("error: can't set the time for %s\n", filename);
- } else {
- pbr.fileParam.ioNamePtr = (StringPtr)filename;
- pbr.fileParam.ioVRefNum = pbr.fileParam.ioFVersNum =
- pbr.fileParam.ioFDirIndex = 0;
- err = PBGetFInfo(&pbr, 0L);
- pbr.fileParam.ioFlMdDat = pbr.fileParam.ioFlCrDat = m_time;
- if (err == noErr)
- err = PBSetFInfo(&pbr, 0L);
- if (err != noErr)
- printf("error: can't set the time for %s\n", filename);
- }
-
- /* set read-only perms if needed */
- if ((err == noErr) && pInfo->read_only) {
- if (hfsflag) {
- hpbr.fileParam.ioNamePtr = (StringPtr)filename;
- hpbr.fileParam.ioVRefNum = gnVRefNum;
- hpbr.fileParam.ioDirID = glDirID;
- err = PBHSetFLock(&hpbr, 0);
- } else
- err = SetFLock((ConstStr255Param)filename, 0);
- }
- PtoCstr(filename);
-
- } /* end function set_file_time_and_close() (Mac) */
-
-
-
-
-
- /************************/
- /* Function IsHFSDisk() */
- /************************/
-
- static int IsHFSDisk(short wRefNum)
- {
- /* get info about the specified volume */
- if (hfsflag == true) {
- HParamBlockRec hpbr;
- Str255 temp;
- short wErr;
-
- hpbr.volumeParam.ioCompletion = 0;
- hpbr.volumeParam.ioNamePtr = temp;
- hpbr.volumeParam.ioVRefNum = wRefNum;
- hpbr.volumeParam.ioVolIndex = 0;
- wErr = PBHGetVInfo(&hpbr, 0);
-
- if (wErr == noErr && hpbr.volumeParam.ioVFSID == 0
- && hpbr.volumeParam.ioVSigWord == 0x4244) {
- return true;
- }
- }
-
- return false;
- } /* IsHFSDisk */
-
-
-
-
-
- /************************/
- /* Function macfstest() */
- /************************/
-
- void macfstest(int vrefnum)
- {
- Str255 st;
-
- /* is this machine running HFS file system? */
- if (FSFCBLen <= 0) {
- hfsflag = false;
- }
- else
- {
- hfsflag = true;
- }
-
- /* get the file's volume reference number and directory ID */
- if (hfsflag == true) {
- WDPBRec wdpb;
- OSErr err = noErr;
-
- if (vrefnum != 0) {
- wdpb.ioCompletion = false;
- wdpb.ioNamePtr = st;
- wdpb.ioWDIndex = 0;
- wdpb.ioVRefNum = vrefnum;
- err = PBHGetVol(&wdpb, false);
-
- if (err == noErr) {
- wAppVRefNum = wdpb.ioWDVRefNum;
- lAppDirID = wdpb.ioWDDirID;
- }
- }
-
- /* is the disk we're using formatted for HFS? */
- hfsflag = IsHFSDisk(wAppVRefNum);
- }
-
- return;
- } /* mactest */
-
-
-
-
-
- /***********************/
- /* Function macmkdir() */
- /***********************/
-
- int macmkdir(char *path, short nVRefNum, long lDirID)
- {
- OSErr err = -1;
-
- if (path != 0 && strlen(path)<256 && hfsflag == true) {
- HParamBlockRec hpbr;
- Str255 st;
-
- CtoPstr(path);
- if ((nVRefNum == 0) && (lDirID == 0))
- {
- hpbr.fileParam.ioNamePtr = st;
- hpbr.fileParam.ioCompletion = NULL;
- err = PBHGetVol((WDPBPtr)&hpbr, false);
- nVRefNum = hpbr.wdParam.ioWDVRefNum;
- lDirID = hpbr.wdParam.ioWDDirID;
- }
- else
- {
- err = noErr;
- }
- if (err == noErr) {
- hpbr.fileParam.ioCompletion = NULL;
- hpbr.fileParam.ioVRefNum = nVRefNum;
- hpbr.fileParam.ioDirID = lDirID;
- hpbr.fileParam.ioNamePtr = (StringPtr)path;
- err = PBDirCreate(&hpbr, false);
- }
- PtoCstr(path);
- }
-
- return (int)err;
- } /* mkdir */
-
-
-
-
-
- /****************************/
- /* Function ResolveMacVol() */
- /****************************/
-
- void ResolveMacVol(short nVRefNum, short *pnVRefNum, long *plDirID, StringPtr pst)
- {
- if (hfsflag)
- {
- WDPBRec wdpbr;
- Str255 st;
- OSErr err;
-
- wdpbr.ioCompletion = (ProcPtr)NULL;
- wdpbr.ioNamePtr = st;
- wdpbr.ioVRefNum = nVRefNum;
- wdpbr.ioWDIndex = 0;
- wdpbr.ioWDProcID = 0;
- wdpbr.ioWDVRefNum = 0;
- err = PBGetWDInfo( &wdpbr, false );
- if ( err == noErr )
- {
- if (pnVRefNum)
- *pnVRefNum = wdpbr.ioWDVRefNum;
- if (plDirID)
- *plDirID = wdpbr.ioWDDirID;
- if (pst)
- BlockMove( st, pst, st[0]+1 );
- }
- }
- else
- {
- if (pnVRefNum)
- *pnVRefNum = nVRefNum;
- if (plDirID)
- *plDirID = 0;
- if (pst)
- *pst = 0;
- }
- }
-
-
-
-
-
- /**********************/
- /* Function macopen() */
- /**********************/
-
- short macopen(char *sz, short nFlags, short nVRefNum, long lDirID)
- {
- OSErr err;
- Str255 st;
- char chPerms = (!nFlags) ? fsRdPerm : fsRdWrPerm;
- short nFRefNum;
-
- CtoPstr( sz );
- BlockMove( sz, st, sz[0]+1 );
- PtoCstr( sz );
- if (hfsflag)
- {
- if (nFlags > 1)
- err = HOpenRF( nVRefNum, lDirID, st, chPerms, &nFRefNum);
- else
- err = HOpen( nVRefNum, lDirID, st, chPerms, &nFRefNum);
- }
- else
- {
- /*
- * Have to use PBxxx style calls since the high level
- * versions don't support specifying permissions
- */
- ParamBlockRec pbr;
-
- pbr.ioParam.ioNamePtr = st;
- pbr.ioParam.ioVRefNum = gnVRefNum;
- pbr.ioParam.ioVersNum = 0;
- pbr.ioParam.ioPermssn = chPerms;
- pbr.ioParam.ioMisc = 0;
- if (nFlags >1)
- err = PBOpenRF( &pbr, false );
- else
- err = PBOpen( &pbr, false );
- nFRefNum = pbr.ioParam.ioRefNum;
- }
- if ( err )
- return -1;
- else
- return nFRefNum;
- }
-
-
-
-
-
- /***********************/
- /* Function maccreat() */
- /***********************/
-
- short maccreat(char *sz, short nVRefNum, long lDirID, OSType ostCreator, OSType ostType)
- {
- OSErr err;
- Str255 st;
- FInfo fi;
-
- CtoPstr( sz );
- BlockMove( sz, st, sz[0]+1 );
- PtoCstr( sz );
- if (hfsflag)
- {
- err = HGetFInfo( nVRefNum, lDirID, st, &fi );
- if (err == fnfErr)
- err = HCreate( nVRefNum, lDirID, st, ostCreator, ostType );
- else if (err == noErr)
- {
- fi.fdCreator = ostCreator;
- fi.fdType = ostType;
- err = HSetFInfo( nVRefNum, lDirID, st, &fi );
- }
- }
- else
- {
- err = GetFInfo( st, nVRefNum, &fi );
- if (err == fnfErr)
- err = Create( st, nVRefNum, ostCreator, ostType );
- else if (err == noErr)
- {
- fi.fdCreator = ostCreator;
- fi.fdType = ostType;
- err = SetFInfo( st, nVRefNum, &fi );
- }
- }
- if (err == noErr)
- return noErr;
- else
- return -1;
- }
-
-
-
-
-
- /**********************/
- /* Function macread() */
- /**********************/
-
- short macread(short nFRefNum, char *pb, unsigned cb)
- {
- long lcb = cb;
-
- (void)FSRead( nFRefNum, &lcb, pb );
-
- return (short)lcb;
- }
-
-
-
-
-
- /***********************/
- /* Function macwrite() */
- /***********************/
-
- short macwrite(short nFRefNum, char *pb, unsigned cb)
- {
- long lcb = cb;
-
- (void)FSWrite( nFRefNum, &lcb, pb );
-
- return (short)lcb;
- }
-
-
-
-
-
- /***********************/
- /* Function macclose() */
- /***********************/
-
- short macclose(short nFRefNum)
- {
- return FSClose( nFRefNum );
- }
-
-
-
-
-
- /***********************/
- /* Function maclseek() */
- /***********************/
-
- long maclseek(short nFRefNum, long lib, short nMode)
- {
- ParamBlockRec pbr;
-
- if (nMode == SEEK_SET)
- nMode = fsFromStart;
- else if (nMode == SEEK_CUR)
- nMode = fsFromMark;
- else if (nMode == SEEK_END)
- nMode = fsFromLEOF;
- pbr.ioParam.ioRefNum = nFRefNum;
- pbr.ioParam.ioPosMode = nMode;
- pbr.ioParam.ioPosOffset = lib;
- (void)PBSetFPos(&pbr, 0);
- return pbr.ioParam.ioPosOffset;
- }
-
- #endif /* MACOS */
-